import { Vector3, Vector2, BufferAttribute } from "three";
import { BufferGeometry } from "three/src/core/BufferGeometry";
import { Point } from "../types/Point";

/**
 * 生成墙体几何体
 */
export default class WallGeometry extends BufferGeometry {    
    /**根据经纬度坐标数组，高度，和中心点坐标创建墙体几何体
     * 创建不带顶盖的几何体
     * @param lnglatArray 底面顶点坐标数组
     * @param height 几何体高度
     * @param centerLnglat 基准点坐标，大坐标防抖动处理，一般传lnglatArray中第一个点坐标
     */
    public constructor(lnglatArray: Array<Point>, height: number, centerLnglat: Point){
        super();
        this.createWallGeometry(lnglatArray, height, centerLnglat);
    }

    
    /**根据经纬度坐标数组，高度，和中心点坐标创建墙体几何体
     * 创建不带顶盖的几何体
     * @param lnglatArray 底面顶点坐标数组
     * @param height 几何体高度
     * @param centerLnglat 基准点坐标，大坐标防抖动处理，一般传lnglatArray中第一个点坐标
     */
    private createWallGeometry(lnglatArray: Array<Point>, height: number, centerLnglat: Point): BufferGeometry {
        let pointArray = new Array<Vector3>();
        let centerPosition = centerLnglat.toEPSGWeb().clone();

        let pointVector: Point;
        lnglatArray.forEach(element => {
            let currentPoint = new Point(element.x, element.y, element.z, element.EPSGType);
            pointVector = currentPoint.toEPSGWeb();
            pointArray.push(pointVector.sub(centerPosition));
        });

        if (!pointArray[0].equals(pointArray[pointArray.length - 1])) {
            pointArray.push(pointArray[0]);
        }

        let totalDistance = 0;
        for (let i = 1; i < pointArray.length; i++) {
            let previousPoint = pointArray[i - 1];
            let point = pointArray[i];
            totalDistance += point.distanceTo(previousPoint);

            previousPoint = point;
        }

        // let geometry = new BufferGeometry();
        let verticeArray = []; //geometry.vertices;
        let faceArray = []; //geometry.faces;
        let texcoordArray = [];//geometry.faceVertexUvs[0];
        let index = 0;
        let length = pointArray.length;
        let textureBottom = 0;
        let textureTop = 1;
        if (height < 0) { //墙体的高度小于0，纹理的采样要从下到上
            textureBottom = 1;
            textureTop = 0;
        }
        let i = 1;
        let currentIndex = 0;
        let previousIndex = 0;
        let currentDistance = 0;
        let isOver = false;
        for (i = 1; i < length; i++) {
            if (isOver == true) {
                break;
            }

            if (i == 1) {
                currentIndex = i;
                if (currentIndex >= length - 1) {
                    return null;
                }
            } else {
                currentIndex = previousIndex + 1;
            }

            if (currentIndex > length - 1) {
                currentIndex = length - 1;
                isOver = true;
            }

            let firstPoint = pointArray[previousIndex];
            verticeArray.push(firstPoint.x, firstPoint.y, firstPoint.z);

            let secondPoint = pointArray[currentIndex];
            verticeArray.push(secondPoint.x, secondPoint.y, secondPoint.z);

            let thirdCoord = new Vector3(pointArray[currentIndex].x, pointArray[currentIndex].y, pointArray[currentIndex].z + height);
            verticeArray.push(thirdCoord.x, thirdCoord.y, thirdCoord.z);

            let fourCoord = new Vector3(pointArray[previousIndex].x, pointArray[previousIndex].y,
                pointArray[previousIndex].z + height);
            verticeArray.push(fourCoord.x, fourCoord.y, fourCoord.z);

            index = index + 4;
            previousIndex = currentIndex;

            //一个三角形
            faceArray.push(index - 4, index - 3, index - 2);

            //一个三角形
            faceArray.push(index - 4, index - 2, index - 1);

            let pieceDistance = firstPoint.distanceTo(secondPoint);
            currentDistance += pieceDistance;

            let firstPointPercent = (currentDistance - pieceDistance) / totalDistance;
            let secondPointPercent = currentDistance / totalDistance

            let firstPointUV = new Vector2(firstPointPercent, textureBottom);
            texcoordArray.push(firstPointUV.x, firstPointUV.y);
            let secondPointUV = new Vector2(secondPointPercent, textureBottom);
            texcoordArray.push(secondPointUV.x, secondPointUV.y);
            let threePointUV = new Vector2(secondPointPercent, textureTop);
            texcoordArray.push(threePointUV.x, threePointUV.y);

            let fourPointUV = new Vector2(firstPointPercent, textureTop);
            texcoordArray.push(fourPointUV.x, fourPointUV.y);

        }
        this.setIndex(faceArray);
        this.setAttribute('position', new BufferAttribute(new Float32Array(verticeArray), 3));

        this.setAttribute('uv', new BufferAttribute(new Float32Array(texcoordArray), 2));
        this.computeVertexNormals();
        // geometry.computeVertexNormals();
        // material.side = FrontSide; //DoubleSide; // BackSide FrontSide
        // material.shininess = 1;

        // let buffGeom = new BufferGeometry();
        // buffGeom.fromGeometry(geometry);
        this['pointArray'] = pointArray;
        // return geometry;
    }
}